package org.zhaya.sdk.processors;

import com.google.common.collect.Lists;
import io.logz.sawmill.Doc;
import io.logz.sawmill.ProcessResult;
import io.logz.sawmill.Processor;
import io.logz.sawmill.annotations.ProcessorProvider;
import io.logz.sawmill.exceptions.ProcessorConfigurationException;
import io.logz.sawmill.utilities.JsonUtils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;

import java.util.*;

@ProcessorProvider(
        type = "lowerCase",
        factory = LowerCaseProcessor.Factory.class
)
public class LowerCaseProcessor implements Processor {

    private final List<String> field;

    public LowerCaseProcessor(List<String> path) {
        this.field = Objects.requireNonNull(path, "field cannot be null");
    }

    @Override
    public ProcessResult process(Doc doc) throws InterruptedException {
        ArrayList<String> targetList = Lists.newArrayList();

        for (String targetPath : this.field) {
            if (!doc.hasField(targetPath, String.class)) {
                targetList.add(targetPath);
            } else {
                String value = doc.getField(targetPath);
                doc.addField(targetPath, value.toLowerCase());
            }
        }
        if (!targetList.isEmpty()) {
            return ProcessResult.failure(String.format("failed to lowercase fields in path [%s], fields are missing or not instance of [%s]", targetList, String.class));
        } else {
            return ProcessResult.success();
        }
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Configuration implements Processor.Configuration {
        private List<String> field;
    }

    public static class Factory implements Processor.Factory {
        public Factory() {
        }

        @Override
        public LowerCaseProcessor create(Map<String, Object> config) {
            Object field = config.get("field");
            if (field instanceof String) {
                List<Object> object = Collections.singletonList(field);
                config.put("field", object);
            }
            Configuration lowerCaseConfig = JsonUtils.fromJsonMap(Configuration.class, config);
            if (CollectionUtils.isEmpty(lowerCaseConfig.getField())) {
                throw new ProcessorConfigurationException("failed to parse lowerCase processor config, could not resolve field");
            } else {
                return new LowerCaseProcessor(lowerCaseConfig.getField());
            }
        }
    }
}
